/*
 *
 * Copyright (c) 2020 The Raptor Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef RAPTOR_LITE_SRC_WINDOWS_CONNECTION_H_
#define RAPTOR_LITE_SRC_WINDOWS_CONNECTION_H_

#include <stddef.h>
#include <stdint.h>
#include <memory>

#include "raptor-lite/utils/slice_buffer.h"
#include "raptor-lite/utils/status.h"

#include "src/windows/iocp_thread.h"

namespace raptor {

class EndpointImpl;
class PollingThread;
class ProtocolHandler;

namespace internal {
class EventReceivingService;
class NotificationTransferService;
} // namespace internal

class Connection final {

public:
    explicit Connection(std::shared_ptr<EndpointImpl> obj);
    ~Connection();

    void Init(int32_t index);
    void SetPollingThread(PollingThread *rs_thread);
    bool SetTransferService(internal::NotificationTransferService *service,
                            internal::EventReceivingService *event_service);
    void SetProtocol(ProtocolHandler *p);
    void Shutdown(bool notify, raptor_error desc);

    bool SendMsg(const Slice &s);
    bool IsOnline();

    // IOCP Event
    raptor_error DoRecvEvent(EventDetail *);
    raptor_error DoSendEvent(EventDetail *);

    int32_t Index() const { return index_; }
    void DoHeartBeat();

private:
    bool OnRecvEvent(size_t size);
    bool OnSendEvent(size_t size);

    // if success return the number of parsed packets
    // otherwise return -1 (protocol error)
    int ParsingProtocol();

    // return true if reach recv buffer tail.
    bool ReadSliceFromRecvBuffer(size_t read_size, Slice &s);

    bool AsyncSend();
    bool AsyncRecv();

private:
    internal::NotificationTransferService *service_;
    internal::EventReceivingService *event_service_;
    ProtocolHandler *proto_;
    PollingThread *rs_thread_;
    bool send_pending_;

    int32_t index_;

    OverLappedEx send_overlapped_;
    OverLappedEx recv_overlapped_;

    SliceBuffer rcv_buffer_;
    SliceBuffer snd_buffer_;

    std::shared_ptr<EndpointImpl> endpoint_;

    uint32_t next_package_size_;
};
} // namespace raptor
#endif // RAPTOR_LITE_SRC_WINDOWS_CONNECTION_H_
